package com.domainlanguage.time;

import com.domainlanguage.internal.FieldReaderUtils;
import org.hibernate.HibernateException;
import org.hibernate.type.ImmutableType;

import java.sql.*;
import java.util.Calendar;

/**
 * Hibernate user type for {@link com.domainlanguage.time.CalendarMinute}.
 *
 * Backed by SQL {@link java.sql.Types.TIMESTAMP}.
 *
 */
public class CalendarMinuteType extends ImmutableType {

    @Override
    public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
        final Timestamp timestamp = rs.getTimestamp(name);
        if (timestamp == null) {
            return null;
        }

        final Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timestamp.getTime());

        return CalendarMinute.dateHourAndMinute(
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH) + 1,
                calendar.get(Calendar.DAY_OF_MONTH),
                calendar.get(Calendar.HOUR_OF_DAY),
                calendar.get(Calendar.MINUTE)
        );
    }

    @Override
    public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
        CalendarMinute calendarMinute = (CalendarMinute) value;

        final CalendarDate date = FieldReaderUtils.readDate(calendarMinute);
        final TimeOfDay timeOfDay = FieldReaderUtils.readTime(calendarMinute);

        final Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, date.breachEncapsulationOf_year());
        calendar.set(Calendar.MONTH, date.breachEncapsulationOf_month() - 1);
        calendar.set(Calendar.DAY_OF_MONTH, date.breachEncapsulationOf_day());
        calendar.set(Calendar.HOUR_OF_DAY, timeOfDay.getHour());
        calendar.set(Calendar.MINUTE, timeOfDay.getMinute());
        // Zero out second and down
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);

        st.setTimestamp(index, new Timestamp(calendar.getTimeInMillis()));
    }

    @Override
    public int sqlType() {
        return Types.TIMESTAMP;
    }

    @Override
    public String toString(Object value) throws HibernateException {
        // TODO
        //throw new UnsupportedOperationException("To and from string is not yet supported for CalendarMinute");
        return value.toString();
    }

    @Override
    public Object fromStringValue(String xml) throws HibernateException {
        // TODO
        throw new UnsupportedOperationException("To and from string is not yet supported for CalendarMinute");
    }

    @Override
    public Class getReturnedClass() {
        return CalendarMinute.class;
    }

    @Override
    public String getName() {
        return "calendarMinute";
    }

}
